#include "modbus_s.h"
typedef int bool;
modbus_t *p;
int len1 = 0;
struct list_head head;
//控制
void *handler_control(void *arg)
{
    printf("进控制\n");
    bool cmd1;   //bool命令
    int cmd2;    //int命令
    float cmd3;  //float命令
    int addrbuf; //接受寄存器地址
    struct list_head *pos;
    struct mb_node_list *tmp;
    //读消息队列
    struct msgbuf msg;
    while (1)
    {
        if (msg_queue_recv("msg", &msg, sizeof(msg), 2, 0) < 0)
        {
            perror("msg_queue_recv err");
            return NULL;
        }
        printf("----------------------%d\n", __LINE__);
        //遍历缓存链表
        list_for_each(pos, &head)
        {
            tmp = list_entry(pos, struct mb_node_list, list);
            if (msg.key == tmp->node.key)
            {
                addrbuf = tmp->node.addr;
                printf("addrbuf:%d\n", addrbuf);
                switch (tmp->node.type)
                {
                case 1:
                    cmd1 = atoi(msg.mdata);
                    break;
                case 2:
                    cmd2 = atoi(msg.mdata);
                    break;
                case 3:
                    cmd3 = (float)atof(msg.mdata);
                    printf("cmd3:%f\n", cmd3);
                    break;
                }
            }
            // printf("err\n");
        }

        printf("----------------------%d\n", __LINE__);
        //将命令写入寄存器
        switch (addrbuf)
        {
        case 40001:
            modbus_write_registers(p, 0, 2, (uint16_t *)&cmd3);
            break;
        case 40003:
            modbus_write_registers(p, 2, 2, (uint16_t *)&cmd3);
            break;
        case 1:
            modbus_write_bit(p, 0, cmd1);
            break;
        case 2:
            modbus_write_bit(p, 1, cmd1);
            break;
        default:
            break;
        }
    }
    pthread_exit(NULL);
    return NULL;
}

//采集
void *handler_gather(void *arg)
{
    uint16_t buf1[2] = {0};
    uint16_t buf2[2] = {0};
    uint16_t buf3[2] = {0};
    uint16_t buf4[2] = {0};
    uint8_t buf5[1] = {0};
    uint8_t buf6[1] = {0};

    struct timespec ts;
    ts.tv_sec = 0;
    ts.tv_nsec = 500000000;
    //共享内存
    //初始化
    struct shm_param sp;
    struct std_node *std;
    if (shm_init(&sp, "shm", 256) < 0)
    {
        printf("shm init err\n");
        return NULL;
    }
    //映射数据点数量
    int *device_total = (int *)shm_getaddr(&sp);
    if (NULL == device_total)
    {
        printf("shm getaddr err\n");
        return NULL;
    }
    //映射数据点
    std = (struct std_node *)(device_total + 1);
    std = std + len1;
    struct std_node *reset_std = std;
    printf("device_total:%d\n", *device_total);
    printf("len1:%d\n", len1);
    int num_t = *device_total - len1;
    //读寄存器的内容
    while (1)
    {
        nanosleep(&ts, NULL);
        //将寄存器的内容存到buf中
        if (modbus_read_input_registers(p, 0, 2, buf1) < 0) //0 2
        {
            perror("modbus_read_input_registers1 err");
            return NULL;
        }
        if (modbus_read_input_registers(p, 2, 2, buf2) < 0) //0 2
        {
            perror("modbus_read_input_registers1 err");
            return NULL;
        }
        if (modbus_read_registers(p, 0, 2, buf3) < 0) //0 2
        {
            perror("modbus_read_registers1 err");
            return NULL;
        }
        if (modbus_read_registers(p, 2, 2, buf4) < 0) //0 2
        {
            perror("modbus_read_registers1 err");
            return NULL;
        }
        if (modbus_read_bits(p, 0, 1, buf5) < 0) //0 1
        {
            perror("modbus_read_bits1 err");
            return NULL;
        }
        if (modbus_read_bits(p, 1, 1, buf6) < 0) //0 1
        {
            perror("modbus_read_bits1 err");
            return NULL;
        }
        // float *p3=buf1;
        // float aaa=*p3;
        // printf("buf1:%0.2f\n",aaa);
        // float *p4=buf2;
        // float aaaa=*p4;
        // printf("buf2:%0.2f\n",aaaa);
        //遍历共享内存
        std = reset_std;
        for (int i = 0; i < num_t; i++, std++)
        {
            switch (std->key)
            {
            case 101:
                memcpy(&(std->new_val.f_val), buf1, 4);
                break;
            case 102:
                memcpy(&(std->new_val.f_val), buf2, 4);
                break;
            case 103:
                memcpy(&(std->new_val.f_val), buf3, 4);
                break;
            case 104:
                memcpy(&(std->new_val.f_val), buf4, 4);
                break;
            case 105:
                memcpy(&(std->new_val.b_val), buf5, 1);
                break;
            case 106:
                memcpy(&(std->new_val.b_val), buf6, 1);
                break;
            }
        }
        memset(buf1, 0, sizeof(buf1));
        memset(buf2, 0, sizeof(buf2));
        memset(buf3, 0, sizeof(buf3));
        memset(buf4, 0, sizeof(buf4));
        memset(buf5, 0, sizeof(buf5));
        memset(buf6, 0, sizeof(buf6));
    }
    pthread_exit(NULL);
    return NULL;
}

int main(int argc, char const *argv[])
{
    //初始化
    //1.构造缓存链表
    INIT_LIST_HEAD(&head);
    printf("缓存链表初始化成功\n");
    //2.解析点表
    char buf[2048] = "";
    FILE *fp = fopen("/mnt/config/node.json", "r");
    if (NULL == fp)
    {
        perror("fopen err");
        return -1;
    }
    fread(buf, 2048, 1, fp);
    printf("打开点表成功\n");
    cJSON *root = cJSON_Parse(buf);
    cJSON *mb_dev = cJSON_GetObjectItem(root, "mb_dev");
    cJSON *ip = cJSON_GetObjectItem(mb_dev, "addr");
    cJSON *port = cJSON_GetObjectItem(mb_dev, "port");
    cJSON *modbus = cJSON_GetObjectItem(root, "modbus");
    cJSON *data = cJSON_GetObjectItem(modbus, "data");
    int len = cJSON_GetArraySize(data);
    cJSON *stm32 = cJSON_GetObjectItem(root, "stm32");
    cJSON *data1 = cJSON_GetObjectItem(stm32, "data");
    len1 = cJSON_GetArraySize(data1);
    struct mb_node_list st[6];
    // 构建链表
    for (int i = 0; i < len; i++)
    {
        cJSON *item = cJSON_GetArrayItem(data, i);
        cJSON *key = cJSON_GetObjectItem(item, "key");
        cJSON *name = cJSON_GetObjectItem(item, "name");
        cJSON *addr = cJSON_GetObjectItem(item, "addr");
        cJSON *type = cJSON_GetObjectItem(item, "type");
        printf("%d %s %d\n", key->valueint, name->valuestring, addr->valueint);
        // 写到结构体中
        st[i].node.key = key->valueint;
        strcpy(st[i].node.name, name->valuestring);
        st[i].node.addr = addr->valueint;
        st[i].node.type = type->valueint;
        // 添加到链表
        list_add(&st[i].list, &head);
        // 输出调试信息
        printf("添加节点: key=%d, name='%s', addr=%d, type=%d\n",
               st[i].node.key, st[i].node.name, st[i].node.addr, st[i].node.type);
    }
    // 检查链表头部
    printf("链表头部信息: next=%p, prev=%p\n", head.next, head.prev);

    //modbus协议通信
    p = modbus_new_tcp(ip->valuestring, port->valueint);
    if (NULL == p)
    {
        perror("modbus_new_tcp err");
        return -1;
    }
    if (modbus_set_slave(p, 1) < 0)
    {
        perror("modbus_set_slave err");
        return -1;
    }
    if (modbus_connect(p) < 0)
    {
        perror("modbus_connect err");
        return -1;
    }
    printf("modbus初始化成功\n");
    //控制线程
    pthread_t tid1;
    if (pthread_create(&tid1, NULL, handler_control, NULL) != 0)
    {
        perror("pthread_create  handler_control err");
        return -1;
    }
    //采集线程
    pthread_t tid2;
    if (pthread_create(&tid2, NULL, handler_gather, NULL) != 0)
    {
        perror("pthread_create handler_gather  err");
        return -1;
    }
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    cJSON_Delete(root);
    modbus_free(p);
    modbus_close(p);
    return 0;
}
